
#include "CCBone.h"
#include "ccMacros.h"
#include "CCSlot.h"

CCBone::CCBone() :
m_parent(NULL),
m_length(0),
m_flags(0) {
	m_originalState.x = 0;
	m_originalState.y = 0;
	m_originalState.rotation = 0;
	m_originalState.scaleX = 1;
	m_originalState.scaleY = 1;
}

CCBone::~CCBone() {
	for(auto it : m_children) {
		it->release();
	}
    for(auto it : m_slotList) {
        it->release();
    }
    m_children.clear();
    m_slotList.clear();
}

CCBone* CCBone::create() {
	CCBone* b = new CCBone();
	return (CCBone*)b->autorelease();
}

void CCBone::addChild(CCBone* bone) {
	m_children.push_back(bone);
	bone->retain();
	bone->setParent(this);
}

void CCBone::addSlot(CCSlot *slot) {
    m_slotList.push_back(slot);
    slot->retain();
}

BoneState& CCBone::getState(CCSkeletalSprite* owner) {
	StateMap::iterator iter = m_stateMap.find(owner);
	if(iter != m_stateMap.end()) {
		return iter->second;
	} else {
		m_stateMap[owner] = m_originalState;
        iter = m_stateMap.find(owner);
		return iter->second;
	}
}

void CCBone::clearState(CCSkeletalSprite* owner) {
	StateMap::iterator iter = m_stateMap.find(owner);
	if(iter != m_stateMap.end())
		m_stateMap.erase(iter);
}

void CCBone::nodeToParentTransform(BoneState &state) { //TODO
    
    state.transform.tx=state.x;
    state.transform.ty=state.y;
    
    if (state.rotation) {
        float radians = CC_DEGREES_TO_RADIANS(state.rotation);
        state.transform.a=state.transform.d=cosf(radians);
        state.transform.b=state.transform.c=sinf(radians);
        state.transform.a*=state.scaleX;
        state.transform.b*=state.scaleX;
        state.transform.c*=-state.scaleY;
        state.transform.d*=state.scaleY;
    }
    else {
        state.transform.a=state.scaleX;
        state.transform.d=state.scaleY;
        state.transform.b=state.transform.c=0.0f;
    }
    
    //reset
    state.x=m_originalState.x;
    state.y=m_originalState.y;
    state.rotation=m_originalState.rotation;
    state.scaleX=m_originalState.scaleX;
    state.scaleY=m_originalState.scaleY;
}


